/*
 * util.h
 *
 *  Created on: Jun 24, 2012
 *      Author: burek
 */

#ifndef UTIL_H_
#define UTIL_H_

#include "../integers.h"

#include "Vec3D.h"

#define LERP(a,b,x) (a + (b - a) * x)

#define PIf (3.14159265358979323846264338327f)
#define RAD_TO_DEG (57.2957795130823208767981548141f)
#define DEG_TO_RAD (0.01745329251994329576923690f)

int randRangeI(int min, int max);
float randRangeF(float min, float max);
float randRangeFS(float min, float max);
int getDistI(int x1, int y1, int x2, int y2);
float getDistF(float x1, float y1, float x2, float y2);
float lerp(float a, float b, float x);
float lerpC(float a, float b, float x);

float getAngleRad(float x1, float y1, float x2, float y2);
float getAngleDeg(float x1, float y1, float x2, float y2);

float angDiffRad(float a1, float a2);
float angDiffDeg(float a1, float a2);

float angDiffSgnRad(float a1, float a2);
void angClampRad(float & angle);

int rPow(int base, int exp);

inline float ease(float t)
{
	return t * t * t * (t * (t * 6 - 15) + 10);
}

template <typename T> inline T rMin(T a, T b)
{
	T delta = b - a;
	return a + (a > b) * delta;
}

template <typename T> inline T rMax(T a, T b)
{
	T delta = b - a;
	return a + (a < b) * delta;
}

template <typename T> inline void clampMax(T &num, const T max)
{
	num = (num > max) ? max : num;
}

template <typename T> inline void clampMin(T &num, const T min)
{
	num = (num < min) ? min : num;
}

template <typename T> inline void clamp(T &num, const T min, const T max)
{
	num = (num > max) ? max : num;
	num = (num < min) ? min : num;
}

template <typename T> T clampMaxRet(const T num, const T max)
{
	return (num > max) ? max : num;
}

template <typename T> T clampMinRet(const T num, const T min)
{
	return (num < min) ? min : num;
}

template <typename T> T clampRet(const T num, const T min, const T max)
{
	T x = (num > max) ? max : num;
	return (x < min) ? min : x;
}

template <typename T> void Rswap(T & a, T & b)
{
	T c = a;
	a = b;
	b = c;
}

bool rayPlaneIntersect(Vec3D point, Vec3D vector, Vec3D surfPoint, Vec3D surfNormal, Vec3D & result);
bool projectRayToZ(Vec3D point, Vec3D vector, float Z, Vec3D & result);

#endif /* UTIL_H_ */
